package cn.edu.sjtu.se.dslab.controller;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.edu.sjtu.se.dslab.auth.CommonVariableModel;
import cn.edu.sjtu.se.dslab.auth.User;
import cn.edu.sjtu.se.dslab.project.PGroup;
import cn.edu.sjtu.se.dslab.project.Project;
import cn.edu.sjtu.se.dslab.service.IAuthService;
import cn.edu.sjtu.se.dslab.service.IPGroupService;
import cn.edu.sjtu.se.dslab.service.IUserProjectService;


@Controller
@RequestMapping(value = "/pgroup")
public class PGroupController {
	private static final Logger logger = Logger.getLogger(PGroupController.class);

	@Resource(name="pgroupService")
	IPGroupService pgroupService;
	
	@Resource(name="userProjectService")
	IUserProjectService userProjectService;
	
	@Resource(name = "authService")
	IAuthService authService;
	
	@RequestMapping(value="/add", method = RequestMethod.POST)
	public String addPGroup(PGroup pgroup){
		pgroupService.addPGroup(pgroup);
		return "redirect:/pgroup/list";
	}
	
	@RequestMapping(value="/{pgroupId}/delete", method= RequestMethod.DELETE)
	@ResponseBody
	public Map<String,String> deletePGroup(@PathVariable(value="pgroupId") Long pgroupId){
		logger.info("Delete PGroup " + pgroupId);
		Map<String, String> responseMap = new HashMap<String, String>();
		try {
			boolean result = pgroupService.deletePGroup(pgroupId);
			if (result) {
				responseMap.put("result", Boolean.TRUE.toString());
			} else {
				responseMap.put("result", Boolean.FALSE.toString());
			}
		} catch (Exception ex) {
			responseMap.put("result", Boolean.FALSE.toString());
		}
		return responseMap;
	}
	

	
	
	@RequestMapping(value="/list", method = RequestMethod.GET)
	public ModelAndView getPGroupList(){
		ModelAndView mav = new ModelAndView();
		mav.setViewName("managePGroup");
		List<PGroup> pgroups = pgroupService.getPGroupList();
		mav.addObject("pgroups", pgroups);
		return mav;
	}
	
	@RequestMapping(value="/{pgroupId}/add_member", method = RequestMethod.GET)
	public ModelAndView addMemberToPGroup(@PathVariable(value="pgroupId") long pgroupId){
		ModelAndView mav = new ModelAndView();
		PGroup pgroup = pgroupService.getPGroupById(pgroupId);
		if (pgroup == null) {
			mav.setViewName("home");
		}else {
			mav.setViewName("add_user_pgroup");
			mav.addObject("pgroup", pgroup);
			//List<User> users = authService.getAllUsers();
			//System.out.println("users size:"+users.size());
			//List<UserFlag> userList = new ArrayList<UserFlag>();
			//Set<User> tempSet = new HashSet<User>(pgroup.getUsers());
			/*for (User user : users) {
				if (pgroup.getUsers() != null) {
					boolean flag = true;
					for (User innerUser : tempSet) {
						if (user.getId() == innerUser.getId()) {
							UserFlag userFlag = new UserFlag(user,true);
							userList.add(userFlag);
							flag = false;
							tempSet.remove(innerUser);
							break;
						}else {
							continue;
						}
					}
					if (flag) {
						UserFlag userFlag = new UserFlag(user,false);
						userList.add(userFlag);
					}
				}else {
					UserFlag userFlag = new UserFlag(user,false);
					userList.add(userFlag);
				}
			}*/
			//System.out.println("userlist size:"+userList.size());
			mav.addObject("users", pgroup.getUsers());
		}
		return mav;
	}
	
	@RequestMapping(value="/{pgroupId}/add_member", method = RequestMethod.POST)
	public String getPGroupInfo(@PathVariable(value="pgroupId") long pgroupId,long[] userIds){
		PGroup pgroup = pgroupService.getPGroupById(pgroupId);
		if (pgroup == null) {
			return "redirect:/home";
		}else {
			Set<User> users = pgroup.getUsers();
			if (users == null) {
				users = new HashSet<User>();
				pgroup.setUsers(users);
			}
			for (long userId : userIds) {
				User temp = authService.getUserById(userId);
				users.add(temp);
			}
			pgroupService.updatePGroup(pgroup);
			return "redirect:/pgroup/"+pgroupId+"/add_member";
		}
	}
	
	@RequestMapping(value="/{pgroupId}/delete_member", method = RequestMethod.POST)
	public String deletePGroupMember(@PathVariable(value="pgroupId") long pgroupId,long[] userIds){
		PGroup pgroup = pgroupService.getPGroupById(pgroupId);
		if (pgroup == null) {
			return "redirect:/home";
		}else {
			if (userIds != null) {
				Set<User> users = pgroup.getUsers();
				for (long userId : userIds) {
					for (User user : users) {
						if (user.getId() == userId) {
							users.remove(user);
							break;
						}
					}
				}
				pgroupService.updatePGroup(pgroup);
			}
			return "redirect:/pgroup/"+pgroupId+"/add_member";
		}
	}
	
	
	@RequestMapping(value="/list/{pgroupId}", method = RequestMethod.GET)
	public ModelAndView getPGroupInfo(@PathVariable(value="pgroupId") Long pgroupId){
		ModelAndView mav = new ModelAndView();
		mav.setViewName("pgroup");
		List<PGroup> pgroups = pgroupService.getPGroupList();
		mav.addObject("pgroups", pgroups);
		if(pgroupId != null){
			PGroup pgroup = pgroupService.getPGroupById(pgroupId);
			mav.addObject("pgroup", pgroup);
		}
		return mav;
	}
	
	@RequestMapping(value = "/list/json", method = RequestMethod.GET)
	@ResponseBody
	public Set<PGroup> getPGroupJsonList(){
		Subject user = SecurityUtils.getSubject();
		if (user!= null && user.getPrincipals() != null) {
			CommonVariableModel model = (CommonVariableModel) user.getPrincipals()
					.getPrimaryPrincipal();
			User currentUser = authService.getUserById(model.getUser().getId());
			Set<PGroup> pgroups = currentUser.getpGroups();
			if (pgroups != null) {
				logger.info("user ID" + model.getUser().getUsername() + model.getUser().getId());
				for (PGroup p: pgroups){
					p.setProjects(userProjectService.getListByUserAndGroup(model.getUser(),p));
					p.setUsers(null);
					if (p.getProjects() != null) {
						for (Project project : p.getProjects()) {
							project.setDesignPatternComponents(null);
							project.setPgroup(null);
							project.setModel(null);
							project.setOwner(null);
						}
					}
				}
				logger.info("get the user's groups:"+pgroups.size());
			}
			return pgroups;
		}else {
			logger.error("No user log in!");
		}
		return null;
	}
	@RequestMapping(value="/addPGroups", method = RequestMethod.GET)
	public String addPGroup(){
		return "addPGroups";
	}
}
